﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace cstdx.Proto.Std;

/// <summary>
/// 序列化/反序列化工具类
/// </summary>
public static class SerializationHelper
{
	/// <summary>
	/// 基于小端序的默认反序列化方法（对应Go的struc.Unpack）
	/// </summary>
	/// <param name="data">原始字节数组</param>
	/// <param name="obj">要反序列化到的对象</param>
	public static void DefaultUnmarshal(byte[] data, object obj)
	{
		if (data == null || obj == null)
			throw new ArgumentNullException(data == null ? nameof(data) : nameof(obj));

		using (var ms = new MemoryStream(data))
		using (var reader = new BinaryReader(ms, Encoding.UTF8, true))
		{
			// 反射获取对象的所有字段（按声明顺序，与Go结构体保持一致）
			var fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (var field in fields)
			{
				// 根据字段类型读取对应的数据（小端序）
				if (field.FieldType == typeof(uint))
				{
					field.SetValue(obj, reader.ReadUInt32());
				}
				else if (field.FieldType == typeof(ushort))
				{
					field.SetValue(obj, reader.ReadUInt16());
				}
				else if (field.FieldType == typeof(byte))
				{
					field.SetValue(obj, reader.ReadByte());
				}
				else if (field.FieldType == typeof(int))
				{
					field.SetValue(obj, reader.ReadInt32());
				}
				else if (field.FieldType == typeof(short))
				{
					field.SetValue(obj, reader.ReadInt16());
				}
				// 可根据需要扩展其他类型
				else
				{
					throw new NotSupportedException($"不支持的字段类型: {field.FieldType.Name}");
				}
			}
		}
	}

	/// <summary>
	/// 基于小端序的默认序列化方法（对应Go的struc.Pack）
	/// </summary>
	/// <param name="obj">要序列化的对象</param>
	/// <returns>序列化后的字节数组</returns>
	public static byte[] DefaultMarshal(object obj)
	{
		if (obj == null)
			throw new ArgumentNullException(nameof(obj));

		using (var ms = new MemoryStream())
		using (var writer = new BinaryWriter(ms, Encoding.UTF8, true))
		{
			// 反射获取对象的所有字段（按声明顺序，与Go结构体保持一致）
			var fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (var field in fields)
			{
				// 根据字段类型写入对应的数据（小端序）
				if (field.FieldType == typeof(uint))
				{
					writer.Write((uint)field.GetValue(obj));
				}
				else if (field.FieldType == typeof(ushort))
				{
					writer.Write((ushort)field.GetValue(obj));
				}
				else if (field.FieldType == typeof(byte))
				{
					writer.Write((byte)field.GetValue(obj));
				}
				else if (field.FieldType == typeof(int))
				{
					writer.Write((int)field.GetValue(obj));
				}
				else if (field.FieldType == typeof(short))
				{
					writer.Write((short)field.GetValue(obj));
				}
				// 可根据需要扩展其他类型
				else
				{
					throw new NotSupportedException($"不支持的字段类型: {field.FieldType.Name}");
				}
			}

			return ms.ToArray();
		}
	}
}
